﻿using Cemit.PolyProto;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;

namespace Cemit.PolyServer
{
    public static class ReceiveDynamicMsgHandles
    {
        static Dictionary<PolyServer, Dictionary<string, List<MethodInfo>>> receiveDynamicMethods = new Dictionary<PolyServer, Dictionary<string, List<MethodInfo>>>();

        public static void StartReceiveDynamicMsg(PolyServer server)
        {
            var methods = from method in server.GetType().GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.DeclaredOnly|BindingFlags.NonPublic)
                          let attribute = method.GetCustomAttribute<ReceiveDynamicMsgAttribute>()
                          where attribute != null
                          select (method, attribute);

            int i = methods.Count();
            receiveDynamicMethods.Add(server, new Dictionary<string, List<MethodInfo>>());

            foreach (var item in methods)
            {
                if (!receiveDynamicMethods[server].ContainsKey(item.attribute.TargetKey))
                {
                    receiveDynamicMethods[server].Add(item.attribute.TargetKey, new List<MethodInfo>());
                }
                receiveDynamicMethods[server][item.attribute.TargetKey].Add(item.method);
            }
        }

        public static IEnumerable<D> ReceiveDynamicMsg(this PolyServer server, ClientState clientState, D msg)
        {
            if (!receiveDynamicMethods.ContainsKey(server))
            {
                StartReceiveDynamicMsg(server);
            }

            return from method in receiveDynamicMethods[server][msg.Key]
                   let report = method.Invoke(server, new object[]
                   {
                       new DynamicMsgData 
                       {
                           clientState = clientState,
                           msg = JsonConvert.DeserializeObject<dynamic>(msg.Data).D
                       }
                   })
                   select new D { Index = msg.Index, Data = JsonConvert.SerializeObject(new { D = report }) };

        }
    }
}
